package luj.tool.jnproxyan.proxy.network.https.client;

import io.netty.buffer.ByteBuf;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;

import java.io.IOException;
import java.io.OutputStream;
import java.util.function.Consumer;

public class HttpsCliMaker {

  public interface Cli {

    void send(HttpObject obj);

    OutputStream receiveBytesFrom();

//    sendBytesTo

    void close() throws IOException;
  }

  public HttpsCliMaker(Consumer<HttpObject> inListener, Consumer<ByteBuf> outListener) {
    _inListener = inListener;
    _outListener = outListener;
  }

  public Cli make(String host, int port) throws Exception {
    var channel = new EmbeddedChannel();
    SslContext sslCtx = makeSslCtx();

    channel.pipeline()
        .addLast(new OutputListenHandler(channel, _outListener))
        .addLast(sslCtx.newHandler(channel.alloc(), host, port))
        .addLast(new SslLogHandler())
//        .addLast(new LoggingHandler())
        .addLast(new HttpClientCodec())
        .addLast(new InputListenHandler(_inListener));

    var receiveFrom = new StreamReceiveFrom();
    receiveFrom._channel = channel;

    var cli = new HttpsCliImpl();
    cli._channel = channel;
    cli._receiveFrom = receiveFrom;
//    cli._sendTo = sendTo;

    return cli;
  }

  private SslContext makeSslCtx() throws Exception {
    return SslContextBuilder.forClient()
        .trustManager(InsecureTrustManagerFactory.INSTANCE)
        .build();
  }

  private final Consumer<HttpObject> _inListener;

  private final Consumer<ByteBuf> _outListener;
}
